import urllib
import logging
import re
from datetime import datetime

import feedparser
import mood

from google.appengine.ext import webapp
from google.appengine.api.urlfetch import fetch

try:
  # This is where simplejson lives on App Engine
  from django.utils import simplejson
except (ImportError):
  import simplejson

FIREHOSE = "https://www.googleapis.com/buzz/v1/activities/@all/@public"
HUB = "http://pubsubhubbub.appspot.com/"
CALLBACK = "http://buzz-mood.appspot.com/pshb/callback"
DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"

class PubsubhubbubUpdatesHandler(webapp.RequestHandler):
  def get(self):
    import mood
    moods = mood.Mood.all().fetch(len(mood.BUCKETS))
    if moods:
      lm = max([m.last_modified for m in moods])
    else:
      lm = datetime.now()
    # Intentional loss of precision
    lm = datetime.strptime(lm.strftime(DATE_FORMAT), DATE_FORMAT)
    ims = None
    if self.request.headers.get('If-Modified-Since'):
      ims = datetime.strptime(
        self.request.headers.get('If-Modified-Since'),
        DATE_FORMAT
      )
    if not ims or (ims and lm > ims):
      json = simplejson.dumps([{
        "name": m.name,
        "lastSummary": m.last_summary,
        "lastContent": m.last_content,
        "lastModified": m.last_modified.isoformat(),
        "counter": m.counter
      } for m in moods])
      logging.info(json)
      self.response.headers['Content-Type'] = \
        'application/json; charset=utf-8'
      # Locale-independent
      self.response.headers['Last-Modified'] = lm.strftime(DATE_FORMAT)
      self.response.out.write(json)
    else:
      self.response.set_status(304)

class PubsubhubbubSubscribeHandler(webapp.RequestHandler):
  def get(self):
    self.post()

  def post(self):
    parameters = {
      "hub.callback": CALLBACK,
      "hub.mode": "subscribe",
      "hub.topic": FIREHOSE,
      "hub.verify": "async"
    }
    fetch(
      HUB,
      method='POST',
      payload=urllib.urlencode(parameters),
      follow_redirects=False
    )

class PubsubhubbubCallbackHandler(webapp.RequestHandler):
  def get(self):
    # Verify request
    hub_mode = self.request.get('hub.mode')
    hub_topic = self.request.get('hub.topic')
    hub_challenge = self.request.get('hub.challenge')
    hub_lease_seconds = self.request.get('hub.lease_seconds')
    hub_verify_token = self.request.get('hub.verify_token')

    if hub_mode == "subscribe":
      if hub_topic == FIREHOSE:
        logging.info('Subscription verified.')
        self.response.set_status(202)
        self.response.out.write(hub_challenge)
      else:
        # We're only interested in the firehose
        self.response.set_status(403)
        self.response.out.write('')
    else:
      # We don't really ever unsubscribe
      self.response.set_status(403)
      self.response.out.write('')

  def post(self):
    # New content pushed
    feed_data = self.request.body
    feed = feedparser.parse(feed_data)
    for entry in feed.entries:
      if hasattr(entry, 'summary'):
        summary = entry.summary
      elif hasattr(entry, 'title'):
        summary = entry.title
      elif hasattr(entry, 'content'):
        summary = entry.content[0].value
      else:
        logging.info('Skipping, couldn\'t find summary.')
        continue
      if hasattr(entry, 'content'):
        content = entry.content[0].value
      elif hasattr(entry, 'summary'):
        content = entry.summary
      elif hasattr(entry, 'title'):
        content = entry.title
      else:
        logging.info('Skipping, couldn\'t find content.')
        continue
      if mood.PATTERN.search(content):
        mood.assign(summary, content)
